package com.pearadmin.process.controller;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.pearadmin.common.nucleus.base.BaseController;
import com.pearadmin.common.nucleus.domain.response.Result;
import com.pearadmin.common.nucleus.domain.response.TableVO;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.editor.constants.ModelDataJsonConstants;
import org.activiti.editor.language.json.converter.BpmnJsonConverter;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/process/model/")
public class ProModelController extends BaseController {

    /**
     * 基础根路径配置
     * */
    private String modelPath = "process/model/";

    @Resource
    private RepositoryService repositoryService;

    @Resource
    private ObjectMapper objectMapper;

      /**
     * 跳转到模型列表页面
     * */
    @GetMapping("view")
    public ModelAndView view(ModelAndView modelAndView)
    {
        modelAndView.setViewName(modelPath+"list");
        return modelAndView;
    }

    /**
     * 跳转编辑器页面
     * @return
     */
    @GetMapping("editor")
    public ModelAndView editor(ModelAndView modelAndView){

        modelAndView.setViewName("process/modeler");

        return modelAndView;
    }

    /**
     * 返回流程模型数据
     * */

    @PostMapping("list")
    public TableVO list(Integer limit, Integer page){
        List<Model> list = repositoryService.createModelQuery().listPage(page,limit);
        TableVO table = new TableVO();
        table.setCode(0);
        table.setCount((long)repositoryService.createModelQuery().list().size());
        table.setData(list);
        return table;
    }


    /**
     * 跳转到流程创建页面
     * */
    @GetMapping("add")
    public ModelAndView add(ModelAndView modelAndView){

        modelAndView.setViewName(modelPath+"add");
        return modelAndView;
    }


    /**
     * 创建模型
     * @param response
     * @param name 模型名称
     * @param key 模型key
     */
    @GetMapping("/create")
    public void create(HttpServletResponse response, String name, String key) throws IOException {
        System.out.println("创建模型入参name："+name+",key:"+key);
        Model model = repositoryService.newModel();
        ObjectNode modelNode = objectMapper.createObjectNode();
        modelNode.put(ModelDataJsonConstants.MODEL_NAME, name);
        modelNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, "");
        modelNode.put(ModelDataJsonConstants.MODEL_REVISION, 1);
        model.setName(name);
        model.setKey(key);
        model.setMetaInfo(modelNode.toString());
        repositoryService.saveModel(model);
        createObjectNode(model.getId());
        response.sendRedirect("/process/model/editor?modelId="+ model.getId());
        System.out.println("创建模型结束，返回模型ID:"+model.getId());
    }

    /**
     * 创建模型时完善ModelEditorSource
     * @param modelId
     */
    @SuppressWarnings("deprecation")
    private void createObjectNode(String modelId){
        System.out.println("创建模型完善ModelEditorSource入参模型ID:"+modelId);
        ObjectNode editorNode = objectMapper.createObjectNode();
        editorNode.put("id", "canvas");
        editorNode.put("resourceId", "canvas");
        ObjectNode stencilSetNode = objectMapper.createObjectNode();
        stencilSetNode.put("namespace","http://b3mn.org/stencilset/bpmn2.0#");
        editorNode.put("stencilset", stencilSetNode);
        try {
            repositoryService.addModelEditorSource(modelId,editorNode.toString().getBytes("utf-8"));
        } catch (Exception e) {
            System.out.println("创建模型时完善ModelEditorSource服务异常："+e);
        }
        System.out.println("创建模型完善ModelEditorSource结束");
    }

    /**
     * 删除模型
     * @param modelId 模型编号
     */
    @PostMapping("deleteById")
    public Result deleteById(String modelId){

        repositoryService.deleteModel(modelId);

        return success("删除成功");
    }

    /**
     * 发布流程
     * @param modelId 模型ID
     * @return
     */
    @ResponseBody
    @RequestMapping("/publish")
    public Object publish(String modelId){
        Map<String, String> map = new HashMap<String, String>();
        try {
            Model modelData = repositoryService.getModel(modelId);
            byte[] bytes = repositoryService.getModelEditorSource(modelData.getId());
            if (bytes == null) {
                return failure("模板数据为空");
            }
            JsonNode modelNode = new ObjectMapper().readTree(bytes);
            BpmnModel model = new BpmnJsonConverter().convertToBpmnModel(modelNode);
            Deployment deployment = repositoryService.createDeployment()
                    .name(modelData.getName())
                    .addBpmnModel(modelData.getKey()+".bpmn20.xml", model)
                    .deploy();
            modelData.setDeploymentId(deployment.getId());
            repositoryService.saveModel(modelData);
            return success("部署成功");
        } catch (Exception e) {
            return failure("部署异常");
        }
    }

}
